package com.king.modules.system.controller;

import java.util.List;

import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.king.common.annotation.Log;
import com.king.common.constant.UserConstants;
import com.king.common.enums.BusinessType;
import com.king.common.exception.AssertHelper;
import com.king.common.utils.SecurityUtils;
import com.king.common.utils.file.FileUploadUtils;
import com.king.common.utils.file.MimeTypeUtils;
import com.king.common.utils.poi.ExcelUtil;
import com.king.common.utils.sign.Md5Utils;
import com.king.common.utils.text.StringUtils;
import com.king.framework.base.controller.YyBaseController;
import com.king.framework.base.domain.vo.AjaxResult;
import com.king.framework.base.domain.vo.LoginUser;
import com.king.framework.base.domain.vo.PageResult;
import com.king.framework.config.ProjectConfig;
import com.king.framework.security.service.JwtTokenService;
import com.king.modules.system.domain.SysRoleEntity;
import com.king.modules.system.domain.SysUserEntity;
import com.king.modules.system.domain.SysUserRoleEntity;
import com.king.modules.system.domain.vo.PasswordVo;
import com.king.modules.system.domain.vo.UserRolesForm;
import com.king.modules.system.service.SysConfigService;
import com.king.modules.system.service.SysOrgService;
import com.king.modules.system.service.SysUserService;

/**
 * 用户信息
 * 
 * @author king
 */
@RestController
@RequestMapping("/system/user")
public class SysUserController extends YyBaseController<SysUserEntity> {
	
	@Autowired
	private SysUserService userService;
	@Autowired
	private JwtTokenService tokenService;
	@Autowired
	private SysConfigService sysConfigService;
	@Autowired
	private SysOrgService orgService;
	

	@Log(title = "用户管理", businessType = BusinessType.EXPORT)
	@PreAuthorize("@sps.hasAuthority('system:user:export')")
	@PostMapping("/export")
	public void export(HttpServletResponse response, SysUserEntity user) {
		List<SysUserEntity> list = userService.selectUserList(user);
		ExcelUtil<SysUserEntity> util = new ExcelUtil<SysUserEntity>(SysUserEntity.class);
		util.exportExcel(response, list, "用户数据");
	}

	@Log(title = "用户管理", businessType = BusinessType.IMPORT)
	@PreAuthorize("@sps.hasAuthority('system:user:import')")
	@PostMapping("/importData")
	public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception {
		ExcelUtil<SysUserEntity> util = new ExcelUtil<SysUserEntity>(SysUserEntity.class);
		List<SysUserEntity> userList = util.importExcel(file.getInputStream());
		Long operUserId = getUserId();
		String message = userService.importUser(userList, updateSupport, operUserId);
		return success(message);
	}

	@PostMapping("/importTemplate")
	public void importTemplate(HttpServletResponse response) {
		ExcelUtil<SysUserEntity> util = new ExcelUtil<SysUserEntity>(SysUserEntity.class);
		util.importTemplateExcel(response, "用户数据");
	}



	/**
	 * 重置密码
	 */
	@PreAuthorize("@sps.hasAuthority('system:user:resetPwd')")
	@Log(title = "用户管理", businessType = BusinessType.UPDATE)
	@PostMapping("/resetPwd")
	public AjaxResult resetPwd(@RequestBody SysUserEntity user) {
		userService.checkUserAllowed(user);
		userService.checkUserDataScope(user.getId());
		user.setPassword(SecurityUtils.encryptPassword(Md5Utils.hash(sysConfigService.selectConfigByKey("sys.user.initPassword"))));
		return toAjax(userService.updateUserPwd(user.getId(), getUserId(), user.getPassword()));
	}
	
	/**
	 * 重置密码
	 */
	@Log(title = "个人信息", businessType = BusinessType.UPDATE)
	@PostMapping("/changePwd")
	public AjaxResult changePwd(@RequestBody PasswordVo passworVo) {
		LoginUser loginUser = getLoginUser();
		String password = userService.getById(loginUser.getUserId()).getPassword();
		String oldpassword = passworVo.getOldpassword();
		String newpassword = passworVo.getNewpassword();
        AssertHelper.getInstance().checkException(!SecurityUtils.matchesPassword(oldpassword, password), "修改密码失败，旧密码错误");
        AssertHelper.getInstance().checkException(SecurityUtils.matchesPassword(newpassword, password), "新密码不能与旧密码相同");
		
//        PasswordChecker pc = new PasswordChecker();
//        AssertHelper.getInstance().checkException(!pc.check(newpassword), "密码必须由(字母+数字)8-20位组成");
		
		if (userService.updateUserPwd(loginUser.getUserId(),loginUser.getUserId(),SecurityUtils.encryptPassword(newpassword)) > 0) {
			// 更新缓存用户密码
			loginUser.getUser().setPassword(SecurityUtils.encryptPassword(newpassword));
			tokenService.setLoginUser(loginUser);
			return success();
		}
		return error("修改密码异常，请联系管理员");
	}


	/**
	 * 状态修改
	 */
	@PreAuthorize("@sps.hasAuthority('system:user:edit')")
	@Log(title = "用户管理", businessType = BusinessType.UPDATE)
	@PutMapping("/changeStatus")
	public AjaxResult changeStatus(@RequestBody SysUserEntity user) {
		userService.checkUserAllowed(user);
		userService.checkUserDataScope(user.getId());
		user.setMr(getUserId());
		return toAjax(userService.updateUserStatus(user));
	}
	
	
	/**
	 * 根据用户编号获取详细信息
	 */
	@GetMapping(value = "/getUserInfo")
	public AjaxResult getUserInfo() {
		Long userId = SecurityUtils.getUserId();
		SysUserEntity user = userService.selectUserById(userId);
		user.setOrgName(orgService.getById(user.getOrgid()).getNodename());
		return success(user);
	}
	
	/**
	 * 个人信息
	 */
//	@GetMapping("/getProfile")
//	public AjaxResult getProfile() {
//		LoginUser loginUser = getLoginUser();
//		SysUserEntity user = loginUser.getUser();
//		AjaxResult ajax = AjaxResult.success(user);
//		ajax.put("roleGroup", userService.selectUserRoles(loginUser.getUserId()));
//		return ajax;
//	}
	
	/**
	 * 头像上传
	 */
	@Log(title = "用户头像", businessType = BusinessType.UPDATE)
	@PostMapping("/avatar")
	public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file) throws Exception {
		if (!file.isEmpty()) {
			LoginUser loginUser = getLoginUser();
			String avatar = FileUploadUtils.upload(ProjectConfig.getAvatarPath(), file, MimeTypeUtils.IMAGE_EXTENSION);
			if (userService.updateUserAvatar(loginUser.getUserId(), avatar)) {
				AjaxResult ajax = AjaxResult.success();
				ajax.put("imgUrl", avatar);
				// 更新缓存用户头像
				loginUser.getUser().setAvatar(avatar);
				tokenService.setLoginUser(loginUser);
				return ajax;
			}
		}
		return error("上传图片异常，请联系管理员");
	}

	/**
	 * 修改用户
	 */
	@Log(title = "个人信息", businessType = BusinessType.UPDATE)
	@PostMapping("/updateProfile")
	public AjaxResult updateProfile(@RequestBody SysUserEntity user) {
		LoginUser loginUser = getLoginUser();
		SysUserEntity sysUser = loginUser.getUser();
		user.setUserName(sysUser.getUserName());
		if (StringUtils.isNotEmpty(user.getPhonenumber())
				&& UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) {
			return error("修改用户'" + user.getUserName() + "'失败，手机号码已存在");
		}
		if (StringUtils.isNotEmpty(user.getEmail())
				&& UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user))) {
			return error("修改用户'" + user.getUserName() + "'失败，邮箱账号已存在");
		}
		user.setId(sysUser.getId());
		user.setPassword(null);
		if (userService.updateUserProfile(user) > 0) {
			// 更新缓存用户信息
			sysUser.setNickName(user.getNickName());
			sysUser.setPhonenumber(user.getPhonenumber());
			sysUser.setAvatar(user.getAvatar());
			sysUser.setEmail(user.getEmail());
			sysUser.setSex(user.getSex());
			sysUser.setMemo(user.getMemo());
			tokenService.setLoginUser(loginUser);
			return error();
		}
		return error("修改个人信息异常，请联系管理员");
	}

	
	
	/**
	 * 用户未选的角色
	 * @param userRole
	 * @return
	 */
	@PostMapping("/unSelectRoles")
	public AjaxResult unSelectRoles(@RequestBody SysUserRoleEntity userRole) {
		startPage();
		List<SysRoleEntity> list = userService.unSelectRoles(userRole);
		return success( new PageResult<SysRoleEntity>(list));
	}
	
	
	/**
	 * 用户已选的角色
	 * @param userRole
	 * @return
	 */
	@PostMapping("/inSelectRoles")
	public AjaxResult inSelectRoles(@RequestBody SysUserRoleEntity userRole) {
		startPage();
		List<SysRoleEntity> list = userService.inSelectRoles(userRole);
		return success( new PageResult<SysRoleEntity>(list));
	}
	
	
	/**
	 * 批量取消授权用户
	 */
	@PreAuthorize("@sps.hasAuthority('system:user:edit')")
	@Log(title = "用户管理", businessType = BusinessType.GRANT)
	@PostMapping("/cancelRoles")
	public AjaxResult cancelRoles(@RequestBody UserRolesForm userRoles) {
		return toAjax(userService.deleteAuthRoles(userRoles.getUserId(), userRoles.getRoleIds()));
	}

	/**
	 * 批量选择用户授权
	 */
	@PreAuthorize("@sps.hasAuthority('system:user:edit')")
	@Log(title = "用户管理", businessType = BusinessType.GRANT)
	@PostMapping("/selectRoles")
	public AjaxResult selectRoles(@RequestBody UserRolesForm userRoles) {
		return toAjax(userService.insertAuthRoles(userRoles.getUserId(), userRoles.getRoleIds()));
	}

}
